/**
 * 添加拦截器
 *   拦截request请求
 *   拦截uploadFile请求
 * TODO
 * 1.非http开头，需要拼接地址
 * 2.添加小程序请求头，token等
 * 3.请求超时时间
 * 4.请求头标识
 */

import { useMemberStore } from "@/stores"

const baseURL = 'https://pcapi-xiaotuxian-front-devtest.itheima.net'

// 添加拦截器
uni.addInterceptor('request', {
  // 请求前触发
  invoke(args: UniApp.RequestOptions) {
    // 添加请求地址
    if (args.url.indexOf('http') !== 0) {
      args.url = baseURL + args.url
    }
    // 设置超时时间
    args.timeout = 10000

    args.header = {
      ...args.header,
      'source-client': 'miniapp',
    }
    const store = useMemberStore()
    store.profile?.token && (args.header.Authorization = store.profile.token)
    console.log('请求拦截器', args)
  },
})
uni.addInterceptor('uploadFile', {
  invoke(args) {
    // 添加请求地址
    args.url = baseURL + args.url
  },
})

/**
 * 封装请求方法
 * 1. 请求成功返回Promise对象
 *  1.1 提取核心数据res.data
 *  1.2 添加泛型，支持泛型
 * 2.请求失败返回Promise对象
 */

// 返回数据的基本结构
interface Data<T> {
  code: string
  result: T
  msg: string
}

export const request = <T>(options: UniApp.RequestOptions) => {
  return new Promise<Data<T>>((resolve, reject) => {
    uni.request({
      ...options,
      success(res) {
        // 只有2xx的响应码才算成功
        if (res.statusCode >= 200 && res.statusCode < 300) {
          // 提取核心数据res.data 进行类型断言
          resolve(res.data as Data<T>)
        } else if (res.statusCode == 401) {
          // 401其实网络是有响应的，这里主动错误清理用户信息 跳转到登陆页面
          const memberStore = useMemberStore()
          memberStore.clearProfile()
          uni.navigateTo({
            url: '/pages/login/login',
          })
          reject(res)
        } else {
          // 其他错误
          uni.showToast({
            title: (res.data as Data<T>).msg || '请求失败',
            icon: 'none',
          })
          reject(res)
        }
      },
      fail(err) {
        // 提示用户网络失败
        uni.showToast({
          title: '网络错误，请换个网络试试',
          icon: 'none',
        })
        reject(err)
      },
    })
  })
}
